package com.mes.spc.util;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.math3.distribution.NormalDistribution;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.regex.Pattern;

public class SpcCalUtil {
	//均值图 控制限计算系数 A2 2-25
    public static double[] A2ConstantNum = {1.8800d,1.0230d,0.7290d,0.5770d,0.4830d,0.1490d,0.3730d,0.3370d,0.3080d,0.2850d,0.2660d,0.2490d,0.2350d,0.2230d,0.2120d,0.2030d,0.1940d,0.1870d,0.1800d,0.1730d,0.1670d,0.1620d,0.1570d,0.1530d};
    public static double[] D2ConstantNum = {1.1280d,1.6930d,2.0590d,2.3260d,2.5340d,2.7040d,2.8470d,2.9700d,3.0780d,3.1730d,3.2580d,3.3360d,3.4070d,3.4720d,3.5320d,3.5880d,3.6400d,3.6890d,3.7350d,3.7780d,3.8190d,3.8580d,3.8950d,3.9310d};
    //极差R图 D3 2-25
    public static double[] D3ConstantNum = {0.0000d,0.0000d,0.0000d,0.0000d,0.0000d,0.0760d,0.1360d,0.1840d,0.2230d,0.2560d,0.2830d,0.3070d,0.3280d,0.3470d,0.3630d,0.7380d,0.3910d,0.4030d,0.4150d,0.4250d,0.4340d,0.4430d,0.4510d,0.4590d};
    //极差R图 D4 2-25
    public static double[] D4ConstantNum = {3.2670d,2.5740d,2.2820d,2.1140d,2.0040d,1.9240d,1.8640d,1.8160d,1.7770d,1.7440d,1.7170d,1.6930d,1.6720d,1.6530d,1.6370d,1.6220d,1.6080d,1.5970d,1.5850d,1.5750d,1.5660d,1.5570d,1.5480d,1.5410d};
    //标准差S图B3 2-25
    public static double[] B3ConstantNum = {0.0000d,0.0000d,0.0000d,0.0000d,0.0300d,0.1180d,0.1850d,0.2390d,0.2840d,0.3210d,0.3540d,0.3820d,0.4060d,0.4280d,0.4400d,0.4660d,0.4820d,0.4970d,0.5100d,0.5230d,0.5340d,0.5450d,0.5550d,0.5650d};
    //标准差S图B4 2-25
    public static double[] B4ConstantNum = {3.2670d,2.5680d,2.2660d,2.0890d,1.9700d,1.8820d,1.8150d,1.7610d,1.7160d,1.6790d,1.6460d,1.6180d,1.5940d,1.5720d,1.5520d,1.5340d,1.5180d,1.5030d,1.4900d,1.4770d,1.4660d,1.4550d,1.4450d,1.4350d};
    //移动极差IMR D4 2-10
    public static double[] D4SConstantNum = {3.2670d,2.5740d,2.2820d,2.1140d,2.0040d,1.9240d,1.8640d,1.8160d,1.7770d};
    //移动极差IMR D3 2-10
    public static double[] D3SConstantNum = {0.0000d,0.0000d,0.0000d,0.0000d,0.0000d,0.0760d,0.1360d,0.1840d,0.2230d};
    //移动极差IMR E2 2-10
    public static double[] E2SConstantNum = {2.6600d,1.7720d,1.4570d,1.2900d,1.1840d,1.1090d,1.0540d,1.0100d,0.9750d};
    //移动极差IMR d3 2-25
    public static double[] d3ConstantNum = {0.8525d,0.8884d,0.8798d,0.8641d,0.848d,0.8332d,0.8198d,0.8078d,0.7971d,0.7873d,0.7785d,0.7704d,0.763d,0.7562d,0.7499d,0.7441d,0.7386d,0.7335d,0.7287d,0.7242d,0.7199d,0.7159d,0.7121d,0.7084d};

    public static double ErrNum = 123321;

	public static double stDev(double[] arrData) //计算标准偏差
    {
        double xSum = 0F;
        double xAvg = 0F;
        double sSum = 0F;
        double tmpStDev = 0F;
        int arrNum = arrData.length;
        for (int i = 0; i < arrNum; i++)
        {
            xSum += arrData[i];
        }
        xAvg = xSum / arrNum;
        for (int j = 0; j < arrNum; j++)
        {
            sSum += ((arrData[j] - xAvg) * (arrData[j] - xAvg));
        }
        tmpStDev = Float.parseFloat(Math.sqrt((sSum / (arrNum - 1)))+"");
        return tmpStDev;
    }

    public static double StandardDiviation(double[] x) {
        int m=x.length;
        double sum=0;
        for(int i=0;i<m;i++){//求和
            sum+=x[i];
        }
        double dAve=sum/m;//求平均值
        double dVar=0;
        for(int i=0;i<m;i++){//求方差
            dVar+=(x[i]-dAve)*(x[i]-dAve);
        }
        return Float.parseFloat(Math.sqrt(dVar/m)+"");
    }

    public static double cp(double UpperLimit, double LowerLimit, double StDev)
    {
        double tmpV = 0F;
        tmpV = UpperLimit - LowerLimit;
        return Math.abs(tmpV / (6.0f * StDev));
    }

    public static double sum(double[] arrData)
    {
        double tmpSum = 0F;
        for (int i = 0; i < arrData.length; i++)
        {
            tmpSum += arrData[i];
        }
        return tmpSum;
    }

    public static double avage(double[] arrData)
    {
        double tmpSum = 0F;
        for (int i = 0; i < arrData.length; i++)
        {
            tmpSum += arrData[i];
        }
        return tmpSum / arrData.length;
    }
    public static int maxInt(int[] arrData)
    {
        int tmpMax = 0;
        for (int i = 0; i < arrData.length; i++)
        {
            if (tmpMax < arrData[i])
            {
                tmpMax = arrData[i];
            }
        }
        return tmpMax;
    }
    public static double max(double[] arrData)
    {
        double tmpMax = 0;
        for (int i = 0; i < arrData.length; i++)
        {
            if (tmpMax < arrData[i])
            {
                tmpMax = arrData[i];
            }
        }
        return tmpMax;
    }
    public static double min(double[] arrData)
    {
        double tmpMin = arrData[0];
        for (int i = 1; i < arrData.length; i++)
        {
            if (tmpMin > arrData[i])
            {
                tmpMin = arrData[i];
            }
        }
        return tmpMin;
    }
    public static double cpkU(double UpperLimit, double Avage, double StDev)
    {
        double tmpV = 0F;
        tmpV = UpperLimit - Avage;
        return tmpV / (3 * StDev);
    }
    public static double cpkL(double LowerLimit, double Avage, double StDev)
    {
        double tmpV = 0F;
        tmpV = Avage - LowerLimit;
        return tmpV / (3 * StDev);
    }
    public static double cpk(double CpkU, double CpkL)
    {
        return Math.min(CpkU, CpkL);
    }

    //计算出现频次
    public static int[] frequency(double[] array,double[] tags)
    {
        Arrays.sort(array);
        Arrays.sort(tags);
        if(array==null||tags==null||array.length==0||array.length==0)
            throw new IllegalArgumentException("数组为空");
        int[] res=new int[tags.length+1];
        int count=0;

        for(int i=0;i<array.length;i++)
        {
            if(count>=tags.length)
                break;
            if(array[i]<=tags[count])
                res[count]+=1;
            else
            {
                i--;
                count++;
            }
        }
        //剩余的
        int sum=0;
        for(int i=0;i<res.length-1;i++)
            sum+=res[i];
        res[res.length-1]=array.length-sum;
        return res;
    }

    /**
     * 获取正态分布点值
     * @param x
     * @param mean
     * @param std
     * @return
     */
    public static double getNormalValue(double x, double mean, double std) {
        return Math.exp(
                -1.0* (x - mean) * (x - mean) / (2 * std * std))
                / Math.sqrt(2 * Math.PI * std * std
        );
    }

    public static double f(double x)
    {
        double f = Math.exp(-x * x / 2) / Math.sqrt(2 * Math.PI);
        return f;
    }
    //计算性能
    public static double GetP(double b)
    {
        int S = 2;
        double Q = 0;
        while (true)
        {
            double a = b - S;
            int M = 1, N = 1, k = 1, m = 1;
            double ep, I, h;
            ep = 0.000000000001;
            h = b - a;
            I = h * (f(a) + f(b)) / 2;
            double[][] T = new double[5000][5000];
            T[1][1] = I;
            while (1 > 0)
            {
                N = (int)Math.pow(2, m - 1);
                h = h / 2;
                I = I / 2;
                for (int i = 1; i <= N; i++)
                    I = I + h * f(a + (2 * i - 1) * h);
                T[m + 1][1] = I;
                M = 2 * N;
                k = 1;
                while (M > 1)
                {
                    T[m + 1] [k + 1] = (Math.pow(4, k) * T[m + 1][ k] - T[m][ k]) / (Math.pow(4, k) - 1);
                    M = M / 2;
                    k = k + 1;
                }
                if (Math.abs(T[k][k] - T[k - 1][k - 1]) < ep)
                break;
                m = m + 1;
            }
            I = T[k][ k];
            Q = Q + I;
            if (Math.abs(I) < ep)
                return Q;
            b = a; S = 2 * S;
        }
    }
    //保留小数位数
    public static double ZeroFormat(double num,int n)
    {
        BigDecimal bigDecimal=new BigDecimal(num);
        return bigDecimal.setScale(n, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    //计算CDF
    public static double normCDF(double X)
    {
        double B1 = 0.31938153D;
        double B2 = -0.356563782D;
        double B3 = 1.781477937D;
        double B4 = -1.8212515978D;
        double B5 = 1.330274429D;
        double P = 0.2316419D;
        double Z = X;
        if (X < 0.0D) Z = -Z;
        double T = 1.0D / (1.0D + P * Z);
        double CDF = 1.0D - 0.39894228040143D * Math.exp(-0.5D * Z * Z) * (B1 * T + B2 * Math.pow(T, 2.0D) + B3 * Math.pow(T, 3.0D) + B4 * Math.pow(T, 4.0D) + B5 * Math.pow(T, 5.0D));
        if (X < 0.0D) CDF = 1.0D - CDF;
        return CDF;
    }

    /**
     *
     *This method calculates the normal cdf inverse function.
     *<p>
     *Let PHI(x) be the normal cdf.  Suppose that Q calculates
     *1.0 - PHI(x), and that QINV calculates QINV(p) for p in (0.0,.5].
     *Then for p .le. .5, x = PHIINV(p) = -QINV(p).
     *For p .gt. .5, x = PHIINV(p) = QINV(1.0 - p).
     *The formula for approximating QINV is taken from Abramowitz and Stegun,
     *Handbook of Mathematical Functions, Dover, 9th printing,
     *formula 26.2.3, page 933.  The error in x is claimed to
     *be less than 4.5e-4 in absolute value.
     *
     *@param   p    p must lie between 0 and 1.  xnormi returns
     *              the normal cdf inverse evaluated at p.
     */
    public static double xnormi(double p) {
        double arg,t,t2,t3,xnum,xden,qinvp,x,pc;
        final double c[] = {
                2.515517,
                .802853,
                .010328
        };
        final double d[] = {
                1.432788,
                .189269,
                .001308
        };
        if (p <= .5) {
            arg = -2.0*Math.log(p);
            t = Math.sqrt(arg);
            t2 = t*t;
            t3 = t2*t;
            xnum = c[0] + c[1]*t + c[2]*t2;
            xden = 1.0 + d[0]*t + d[1]*t2 + d[2]*t3;
            qinvp = t - xnum/xden;
            x = -qinvp;
            return x;
        }else{
            pc = 1.0 - p;
            arg = -2.0*Math.log(pc);
            t = Math.sqrt(arg);
            t2 = t*t;
            t3 = t2*t;
            xnum = c[0] + c[1]*t + c[2]*t2;
            xden = 1.0 + d[0]*t + d[1]*t2 + d[2]*t3;
            x = t - xnum/xden;
            return x;
        }
    }

    /*
    Here is a copy of the documentation in the FORTRAN code:
    SUBROUTINE NORMP(Z, P, Q, PDF)
    Normal distribution probabilities accurate to 1.e-15.
    Z = no. of standard deviations from the mean.
    P, Q = probabilities to the left & right of Z.   P + Q = 1.
           PDF = the probability density.
    */
    public static double normp(double z) {
        double zabs;
        double p;
        double expntl,pdf;
        final double p0 = 220.2068679123761;
        final double p1 = 221.2135961699311;
        final double p2 = 112.0792914978709;
        final double p3 = 33.91286607838300;
        final double p4 = 6.373962203531650;
        final double p5 = .7003830644436881;
        final double p6 = .3526249659989109E-01;

        final double q0 = 440.4137358247522;
        final double q1 = 793.8265125199484;
        final double q2 = 637.3336333788311;
        final double q3 = 296.5642487796737;
        final double q4 = 86.78073220294608;
        final double q5 = 16.06417757920695;
        final double q6 = 1.755667163182642;
        final double q7 = .8838834764831844E-1;
        final double cutoff = 7.071;
        final double root2pi = 2.506628274631001;

        zabs = Math.abs(z);
        if (z > 37.0) {
            p = 1.0;
            return p;
        }
        if (z < -37.0) {
            p = 0.0;
            return p;
        }
        expntl = Math.exp(-.5*zabs*zabs);
        pdf = expntl/root2pi;
        if (zabs < cutoff) {
            p = expntl*((((((p6*zabs + p5)*zabs + p4)*zabs + p3)*zabs +
                    p2)*zabs + p1)*zabs + p0)/(((((((q7*zabs + q6)*zabs +
                    q5)*zabs + q4)*zabs + q3)*zabs + q2)*zabs + q1)*zabs +
                    q0);
        } else {
            p = pdf/(zabs + 1.0/(zabs + 2.0/(zabs + 3.0/(zabs + 4.0/(zabs + 0.65)))));
        }
        if (z < 0.0) {
            return p;
        } else {
            p = 1.0 - p;
            return p;
        }
    }

    /**
     * 获得Y轴刻度最大值
     * @param USL
     * @param arrayData
     * @return
     */
    public static double getYMaxNum(double USL,double[] arrayData){
        if(USL!=ErrNum){
            return max(ArrayUtils.add(arrayData,USL));
        }else{
            return max(arrayData);
        }
    }

    /**
     * 获得Y轴最小刻度
     * @param LSL
     * @param arrayData
     * @return
     */
    public static double getYMinNum(double LSL,double[] arrayData){
        if(LSL!=ErrNum){
            return min(ArrayUtils.add(arrayData,LSL));
        }else{
            return min(arrayData);
        }
    }

    //判断整数（int）
    public static boolean isInteger(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    //判断浮点数（double和float）
    public static boolean isDouble(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
        return pattern.matcher(str).matches();
    }

    public static void main(String[] args) {
		//double[] arrData = {61.3f,59.3f,59.7f,58.8f,59.7f,55.5f,59.7f,57.3f,60.3f,61.0f,62.6f,58.8f,58.5f,60.3f,59.5f,59.6f,63.3f,60.1f,59.7f,63.7f,58.7f,62.5f,60.0f,59.9f,63.2f,60.7f,60.9f,59.5f,61.4f,59.9f,58.5f,57.8f,60.4f,58.0f,63.9f,57.7f,56.8f,59.3f,61.9f,59.2f,58.7f,57.3f,60.6f,59.7f,61.1f,58.7f,59.3f,60.6f,59.3f,60.4f,55.1f,59.9f,60.5f,64.2f,56.9f,56.9f,55.4f,62.3f,64.7f,59.2f,58.0f,61.1f,61.3f,58.3f,61.6f,61.3f,59.6f,56.9f,62.0f,61.5f,59.3f,58.6f,61.7f,60.7f,61.1f,64.2f,60.5f,57.8f,61.0f,57.5f,61.1f,59.7f,60.6f,60.7f,60.3f,59.5f,57.3f,64.2f,63.2f,62.1f,57.0f,57.8f,61.1f,60.1f,60.0f,60.3f,56.2f,59.5f,58.1f,58.0f};
        double[] arrData = {
                1.88f,2f,1.91f,
                2.4f,2.23f,2.95f,
                3.2f,2.75f,2.73f,
                2.63f,2.97f,1.83f,
                1.69f,2.79f,2.29f,
                3.67f,1.99f,1.69f,
                2.27f,3.076f,2.06f,
                2.25f,1.88f,2.24f,
                2.17f,3.27f,3.52f,
                1.65f,2.31f,1.52f
        };//样本均值

        //样本均值
        double[] sampleAvg = {1.93f,2.527f,2.894f,2.476f,2.256f,2.448f,2.467f,2.124f,2.986f,1.825f};
        //极差均值
        double[] jcAvg = {0.12f,0.72f,0.47f,1.13f,1.1f,1.98f,1.02f,0.37f,1.35f,0.79f};
        double UpperLimit = 4f;
		double LowerLimit = 1f;
		double Avage = avage(sampleAvg);
        double Avagejj = avage(jcAvg);
		double StDev = stDev(arrData);
		double Pp = cp(UpperLimit,LowerLimit,StDev);
		double PpkU = cpkU(UpperLimit, Avage, StDev);
		double PpkL = cpkL(LowerLimit, Avage, StDev);
        double Cp = cp(UpperLimit,LowerLimit,Avagejj/D2ConstantNum[1]);
		double CpkU = cpkU(UpperLimit, Avage, Avagejj/D2ConstantNum[1]);
        double CpkL = cpkL(LowerLimit, Avage, Avagejj/D2ConstantNum[1]);
        double Ca = (Avage-(UpperLimit+LowerLimit)/2)/((UpperLimit-LowerLimit)/2);

        System.out.println("StDev（组内）："+Avagejj/D2ConstantNum[1]);
        System.out.println("正三倍StDev（组内）："+(Avage+3*Avagejj/D2ConstantNum[1]));
        System.out.println("负三倍StDev（组内）："+(Avage-3*Avagejj/D2ConstantNum[1]));
        System.out.println("StDev（整体）："+StDev);
        System.out.println("Ca："+Ca);
        System.out.println("Cp："+Cp);
		System.out.println("CpkU："+CpkU);
		System.out.println("CpkL："+CpkL);
		System.out.println("Cpk："+cpk(CpkU, CpkL));
        System.out.println("Pp："+Pp);
        System.out.println("PpkU："+PpkU);
        System.out.println("PpkL："+PpkL);
        System.out.println("Ppk："+cpk(PpkU, PpkL));
        System.out.println("max："+max(arrData));
        System.out.println("min："+min(arrData));

		double[] tagArray = {55.0f,56.0f,57.0f,58.0f,59.0f,60.0f,61.0f,62.0f,63.0f,64.0f,65.0f};



        double maxNum = SpcCalUtil.max(arrData);
        double minNum = SpcCalUtil.min(arrData);
        double jkNum = maxNum-minNum;
        int groupSize = (int)Math.round(Math.sqrt(arrData.length));//分组数
        double groupGap = (double)(Math.ceil(jkNum/groupSize*1000))/1000;
        groupSize = groupSize+2;
        double[] xArrays = new double[groupSize];
        double tempNum = minNum;
        for(int i = 1;i<groupSize-1;i++){
            xArrays[i]=tempNum+groupGap*i;
        }
        xArrays[0] = xArrays[1]-groupGap;
        xArrays[groupSize-1] = xArrays[groupSize-2]+groupGap;
        int[] ss = frequency(arrData,xArrays);
        System.out.println("frequency："+ss.toString());

        for(double jj:xArrays){
            System.out.println("--------- "+jj);
        }
        double t1StDev = 2.250197671f;//标准差
        double t2Avage = 10.192f;//平均

//        NormalDistribution distribution = new NormalDistribution(t2Avage,t1StDev);
//        System.out.println("1---："+distribution.cumulativeProbability(3.000f));
//        System.out.println("2---："+distribution.cumulativeProbability(3.625f));
//        System.out.println("3---："+distribution.cumulativeProbability(4.250f));
//        System.out.println("4---："+distribution.cumulativeProbability(4.875f));
//        System.out.println("5---："+distribution.cumulativeProbability(5.500f));
//        System.out.println("6---："+distribution.cumulativeProbability(6.125f));
//        System.out.println("7---："+distribution.cumulativeProbability(6.750f));

        System.out.println("1---："+ getNormalValue(3.000f,t2Avage,t1StDev));
        System.out.println("2---："+ getNormalValue(3.625f,t2Avage,t1StDev));
        System.out.println("3---："+ getNormalValue(4.250f,t2Avage,t1StDev));
        System.out.println("4---："+ getNormalValue(4.875f,t2Avage,t1StDev));
        System.out.println("5---："+ getNormalValue(5.500f,t2Avage,t1StDev));
        System.out.println("6---："+ getNormalValue(6.125f,t2Avage,t1StDev));
        System.out.println("7---："+ getNormalValue(6.750f,t2Avage,t1StDev));

        double UpBdRate_E = (1-GetP((UpperLimit - Avage) / (Avagejj/D2ConstantNum[1])))*1000000;
        double LowBdRate_E = GetP((LowerLimit - Avage) / (Avagejj/D2ConstantNum[1]))*1000000;
        double SumBdRate_E = UpBdRate_E + LowBdRate_E;
        System.out.println("UpBdRate_E---："+ UpBdRate_E);
        System.out.println("LowBdRate_E---："+ LowBdRate_E);
        System.out.println("SumBdRate_E---："+ SumBdRate_E);

        double UpBdRate_G = (1-GetP((UpperLimit - Avage) / StDev))*1000000;
        double LowBdRate_G = GetP((LowerLimit - Avage) / StDev)*1000000;
        double SumBdRate_G = UpBdRate_G + LowBdRate_G;
        System.out.println("UpBdRate_G---："+ UpBdRate_G);
        System.out.println("LowBdRate_G---："+ LowBdRate_G);
        System.out.println("SumBdRate_G---："+ SumBdRate_G);

        double[] groupJk = {0.12d,0.72d,0.47d};
        double[] group1 = {1.88d,2d,1.91d};
        double[] group2 = {2.4d,2.23d,2.95d};
        double[] group3 = {3.2d,2.75d,2.73d};
        double avgGroup1 = avage(group1);
        double avgGroup2 = avage(group2);
        double avgGroup3 = avage(group3);

        double stdevGroup1 = stDev(group1);
        double stdevGroup2 = stDev(group2);
        double stdevGroup3 = stDev(group3);

        double stdevGroup1jk = groupJk[0]/D2ConstantNum[1];
        double stdevGroup2jk = groupJk[1]/D2ConstantNum[1];
        double stdevGroup3jk = groupJk[2]/D2ConstantNum[1];
        System.out.println("-----cpkgroup1："+cpk(cpkU(UpperLimit,avgGroup1,stdevGroup1),cpkL(LowerLimit,avgGroup1,stdevGroup1)));
        System.out.println("-----cpkgroup2："+cpk(cpkU(UpperLimit,avgGroup2,stdevGroup2),cpkL(LowerLimit,avgGroup2,stdevGroup2)));
        System.out.println("-----cpkgroup3："+cpk(cpkU(UpperLimit,avgGroup3,stdevGroup3),cpkL(LowerLimit,avgGroup3,stdevGroup3)));

        System.out.println("-----cpkgroup1："+cpk(cpkU(UpperLimit,avgGroup1,stdevGroup1jk),cpkL(LowerLimit,avgGroup1,stdevGroup1jk)));
        System.out.println("-----cpkgroup2："+cpk(cpkU(UpperLimit,avgGroup2,stdevGroup2jk),cpkL(LowerLimit,avgGroup2,stdevGroup2jk)));
        System.out.println("-----cpkgroup3："+cpk(cpkU(UpperLimit,avgGroup3,stdevGroup3jk),cpkL(LowerLimit,avgGroup3,stdevGroup3jk)));


        NormalDistribution distribution = new NormalDistribution(Avage,StDev);
        for(double a:arrData){
            System.out.println(a+"-----"+distribution.cumulativeProbability(a));
//            System.out.println("-----"+normCDF((a-Avage)/StDev));
            //System.out.println("-----"+normp((a-Avage)/StDev));
            //System.out.println("-----"+xnormi((a-Avage)/StDev));
            //System.out.println(NormalDist.cdf(Avage,StDev,a));
        }
        System.out.println("-----");

        System.out.println("-----"+distribution.inverseCumulativeProbability(0.01));

        double[] arrDataqq = {34,35,36,37,38,39,40,40,41,42,43,44,45,46};
        double[] percentArray = new double[]{
                0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,
                0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
                0.91,0.92,0.93,0.94,0.95,0.96,0.97,0.98,0.99
        };

        NormalDistribution distributionqq = new NormalDistribution(40,3.742);
        for(int i = 0;i<percentArray.length;i++){
            System.out.println("-----oooooZ==== Z："+(distributionqq.inverseCumulativeProbability(percentArray[i])-40)/3.742+
                            "   X："+distributionqq.inverseCumulativeProbability(percentArray[i])+
                            "   Y："+percentArray[i]*100
            );
        }
        System.out.println("-----ooooo"+distributionqq.cumulativeProbability(31.2956));
        System.out.println("-----ooooo"+distributionqq.inverseCumulativeProbability(0.01));

        arrData = new double[]{74.0, 74.0, 75.0, 75.0, 75.0, 76.0, 76.0, 76.0, 76.0, 76.0, 76.0, 76.0, 76.0, 76.0, 76.0, 77.0, 77.0, 77.0, 77.0, 77.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 79.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 81.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 82.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 83.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 84.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 85.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 86.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 87.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 88.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 89.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 91.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 92.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 93.0, 94.0, 94.0, 94.0, 95.0, 95.0, 95.0, 95.0, 95.0, 95.0, 95.0, 96.0, 96.0, 96.0, 98.0, 98.0, 99.0, 99.0, 99.0, 100.0, 101.0, 102.0, 103.0, 103.0, 106.0, 124.0};
        
        Avage = avage(arrData);
        StDev = stDev(arrData);
//        NormalDistribution distribution1 = new NormalDistribution(40,3.742);
        NormalDistribution distribution1 = new NormalDistribution(Avage,StDev);
        Arrays.sort(arrData);
        double tempSum = 0d;
        for(int i=0;i<arrData.length;i++) {
//            System.out.println("++++-----   " +((2d*(i+1)-1)/arrData.length));
                    tempSum+= (-1-((2d*(i+1)-1)/arrData.length)
                            *
                            (Math.log(distribution1.cumulativeProbability(arrData[i]))+
                                    Math.log(1-distribution1.cumulativeProbability(arrData[arrData.length-i-1]))));

//            int tempi = i+1;
//
//            for(int j = i;j<arrData.length;j++){
//                tempSum+=((2d*(j+1)-1)/arrData.length)*(Math.log(distribution1.cumulativeProbability(arrData[j]))+
//                                Math.log(1-distribution1.cumulativeProbability(arrData[arrData.length-j-1])));
//            }
//
        }
        System.out.println("++++-----AD   "+tempSum);
        System.out.println("++++-----   "+tempSum*(1d+0.75d/arrData.length+2.25d/Math.pow(arrData.length,2)));
        double adn = tempSum*(1d+0.75d/arrData.length+2.25d/Math.pow(arrData.length,2));
        double p = 0;
        if(adn<13&&adn>0.6000d){
            p = Math.pow(Math.E,1.2937d - 5.709d * adn + 0.0186d*Math.pow(adn,2));
        }else if(adn<0.600&&adn>0.340){
            p = Math.pow(Math.E,0.9177d - 4.279d * adn-1.38d*Math.pow(adn,2));
        }else if(adn<0.340&&adn>0.200){
            p = 1 - Math.pow(Math.E,-8.318d + 42.796d * adn - 59.938d*Math.pow(adn,2));
        }else if (adn<0.200){
            p = 1 - Math.pow(Math.E,-13.436d + 101.14d * adn - 223.73d*Math.pow(adn,2));
        }
        System.out.println("++++-----P   "+p);
    }
}
